<template>
  <div class="wraper">
    <div class="wraper-header">
      <img
        src="https://font.qqe2.com/css/img/fontstore.svg"
        class="logo"
        alt=""
      />
      <!-- <el-button
        v-for="(item, idx) in toolsArr"
        :key="idx"
        @click="drawQuadratic1(item, idx)"
        >{{ item.name }}</el-button
      > -->
    </div>
    <div class="wraper-canvas" ref="wraperCanvas">
      <canvas id="canvas" ref="canvas" @keydown="keyBoardEvent($event)"></canvas>
    </div>
    <!-- 左侧菜单 -->
    <div class="wraperLeftMenu">
      <div
        :class="[initIdx==idx ? 'contro-item active' : 'contro-item']"
        :key="idx"
        @click="handleTools(item, idx)"
        v-for="(item,idx) in toolsArr"
      >
        <i>{{item.name}}</i>
      </div>
    </div>
  </div>
</template>
  
<script>
// import {fabric} from "fabric";
// import {loadSync} from 'opentype.js'

// import opentype from 'opentype.js'
export default {
  name: "Test",
  data() {
    return {
      canvas: null,
      mouseFrom: { x: null, y: null },
      zoom: window.zoom ? window.zoom : 1,
      zoomPoint: new fabric.Point(0, 0), //初始时缩放原点的位置设为（0,0），这是页面的左上顶点
      lastzoomPoint: { x: 0, y: 0 }, //初始时，前一次缩放原点同样为(0,0)
      lastmousePoint: { x: 0, y: 0 }, //进行缩放，需要对此刻缩放位置进行保存，来计算出缩放原点，此刻初始时设为0,0
      lastzoom: 1, //表示为上一次的缩放倍数，此刻设为1
      relativeMouseX: 0, //表示相对的鼠标位移，用来记录画布的绝对移动距离
      relativeMouseY: 0, //表示相对的鼠标位移，用来记录画布的绝对移动距离
      pathInfo: null,
      pathInfoArr: [],
      drawingObject: null,
      initIdx: 0,
      toolsArr: [
        {
          value: "select",
          name: "选择",
        },
        {
          value: "quadratic",
          name: "钢笔",
        },
        {
          value: "pencil",
          name: "铅笔",
        },
        {
          value: "undo",
          name: "上一步",
        },
        {
          value: "redo",
          name: "下一步",
        },
        
      ],
      currentTool: null,
    };
  },
  mounted() {
    this.initCanvas();
    // this.createRect();
    this.mouseEvent();
    this.drawQuadratic();
  },
  computed: {
    canvasWidth() {
      return window.innerWidth;
    },
    canvasHeight() {
      return this.$refs.wraperCanvas.offsetHeight;
    },
  },
  methods: {
    initCanvas() {
      this.canvas = new fabric.Canvas("canvas",{
        selectable: false,
        selection: false,
      });
      fabric.Object.prototype.originX = fabric.Object.prototype.originY = "center";
      this.canvas.setWidth(this.canvasWidth);
      this.canvas.setHeight(this.canvasHeight);
      this.canvas.on({
        // "object:selected": this.onObjectSelected,
        "object:moving": this.onObjectMoving,
        // "selection:cleared": this.onSelectionCleared,
      });
    },
    keyBoardEvent(e){
        if(e.keyCode == 27){
          // esc事件
          console.log("222");
        }
      
    },
    mouseEvent() {
      this.canvas.on({
        "mouse:down": (o) => {
          this.mouseFrom.x = this.getX(o);
          this.mouseFrom.y = this.getY(o);
          switch (this.currentTool) {
            case "quadratic":
              this.drawAll(this.currentTool);
              break
            case "select":
              this.drawAll(this.currentTool);
              break
              
          }
        },
        "mouse:up": (o) => {},
        // 'mouse:move': (o) => {
        //   console.log("move");
        //   console.log(o);
        // },
        "mouse:wheel": (o) => {
          if (window.event.ctrlKey) {
            /**
             * @description: 放大缩小画布 ctrl + wheel
             * @return {*}
             */
            this.zoom = (o.e.deltaY > 0 ? -0.1 : 0.1) + this.canvas.getZoom();
            this.zoom = Math.max(0.1, this.zoom); //最小为原来的1/10
            this.zoom = Math.min(3, this.zoom); //最大是原来的3倍
            this.zoomPoint = new fabric.Point(o.pointer.x, o.pointer.y);
            this.canvas.zoomToPoint(this.zoomPoint, this.zoom);
            this.resetOriginAfterZoom();
          }
        },
      });
    },
    drawAll(currentTool) {
      /**
       * @description: 绘图
       * @param {*} currentTool
       * @return {*}
       */
      let fabricObject = null
      switch (currentTool) {
        case "select":
          // this.selectable = true;
          break
        case "quadratic":
          const { x, y } = this.mouseFrom;
          // this.pathInfo = "M ";
          if (this.pathInfoArr.length == 0) {
            this.pathInfoArr.push("M");
            this.pathInfoArr.push(x);
            this.pathInfoArr.push(y);
          } else {
            this.pathInfoArr.push("Q");
            this.pathInfoArr.push(x);
            this.pathInfoArr.push(y);
            this.pathInfoArr.push(x);
            this.pathInfoArr.push(y);
          }
          this.pathInfo = this.pathInfoArr.join(' ');
          // console.log(this.pathInfoArr);
          // console.log(this.pathInfo);
          // this.canvas.renderAll();
          fabricObject = new fabric.Path(this.pathInfo, {
            fill: "",
            stroke: "black",
            objectCaching: true,
            // selectable: false
          });
          break
      }
      if (fabricObject) {
          // this.canvas.clearContext(fabricObject)
          // this.canvas.clear()
          this.canvas.add(fabricObject)
          this.canvas.renderAll()
          this.drawingObject = fabricObject
          console.log(this.canvas);
          console.log(this.canvas._objects);
          console.log(this.canvas.getObjects());
        }
    },
    handleTools(tools, idx) {
      this.initIdx = idx
      this.currentTool = tools.value;
      this. canvas.isDrawingMode = false
      switch (this.currentTool) {
        case "quadratic":
          // this.canvas.isDrawingMode = true
          this.canvas.selectable = false;
          break
        case "select":
          this.canvas.selectable = true;
          break
        case "pencil":
          this.canvas.selectable = false;
          this.canvas.isDrawingMode = true;
          break
      }
    },
    onObjectSelected(e) {
      var activeObject = e.target;

      if (activeObject.name == "p0" || activeObject.name == "p2") {
        activeObject.line2.animate("opacity", "1", {
          duration: 200,
          onChange: canvas.renderAll.bind(canvas),
        });
        activeObject.line2.selectable = true;
      }
    },
    onSelectionCleared(e) {
      var activeObject = e.target;
      if (activeObject.name == "p0" || activeObject.name == "p2") {
        activeObject.line2.animate("opacity", "0", {
          duration: 200,
          onChange: canvas.renderAll.bind(canvas),
        });
        activeObject.line2.selectable = false;
      } else if (activeObject.name == "p1") {
        activeObject.animate("opacity", "0", {
          duration: 200,
          onChange: canvas.renderAll.bind(canvas),
        });
        activeObject.selectable = false;
      }
    },
    onObjectMoving(e) {
      if (e.target.name == "p0" || e.target.name == "p2") {
        var p = e.target;
        console.log("eee");
        console.log(e);
        if (p.line1) {
          p.line1.path[0][1] = p.left;
          p.line1.path[0][2] = p.top;
        } else if (p.line3) {
          p.line3.path[1][3] = p.left;
          p.line3.path[1][4] = p.top;
        }
      } else if (e.target.name == "p1") {
        var p = e.target;

        if (p.line2) {
          p.line2.path[1][1] = p.left;
          p.line2.path[1][2] = p.top;
        }
      }
      // else if (e.target.name == "p0" || e.target.name == "p2") {
      //   var p = e.target;

      //   p.line1 && p.line1.set({ x2: p.left, y2: p.top });
      //   p.line2 && p.line2.set({ x1: p.left, y1: p.top });
      //   p.line3 && p.line3.set({ x1: p.left, y1: p.top });
      //   p.line4 && p.line4.set({ x1: p.left, y1: p.top });
      // }
    },
    createRect() {
      let rect = new fabric.Rect({
        top: 50,
        left: 100,
        width: 100,
        height: 70,
        fill: "red",
      });
      // let font = opentype.load('./simsunb.ttf')
      // console.log(font.glyphs);
      this.canvas.add(rect);
    },
    drawQuadratic() {
      // this.pathInfo = "M 65 0 Q 100, 100, 200, 0";
      // this.pathInfo = "M ";
      // let x=this.mouseFrom.x
      // let y=this.mouseFrom.y

      // this.canvas.renderAll();
      let line = new fabric.Path("M 65 0 Q 100, 100, 200, 0", {
        fill: "",
        stroke: "black",
        objectCaching: false,
      });

      line.path[0][1] = 100;
      line.path[0][2] = 100;

      line.path[1][1] = 200;
      line.path[1][2] = 200;

      line.path[1][3] = 300;
      line.path[1][4] = 100;
      line.selectable = false;

      this.canvas.add(line);

      var p1 = this.makeCurvePoint(200, 200, null, line, null);
      p1.name = "p1";
      this.canvas.add(p1);

      var p0 = this.makeCurveCircle(100, 100, line, p1, null);
      p0.name = "p0";
      this.canvas.add(p0);

      var p2 = this.makeCurveCircle(300, 100, null, p1, line);
      p2.name = "p2";
      this.canvas.add(p2);
      console.log(this.canvas);
      console.log(line);
      console.log(p1);
    },
    makeCurveCircle(left, top, line1, line2, line3) {
      var c = new fabric.Circle({
        left: left,
        top: top,
        strokeWidth: 5,
        radius: 12,
        fill: "#fff",
        stroke: "#666",
      });

      c.hasBorders = c.hasControls = false;

      c.line1 = line1;
      c.line2 = line2;
      c.line3 = line3;

      return c;
    },
    makeCurvePoint(left, top, line1, line2, line3) {
      var c = new fabric.Circle({
        left: left,
        top: top,
        strokeWidth: 8,
        radius: 14,
        fill: "#fff",
        stroke: "#666",
      });
      c.hasBorders = c.hasControls = false;

      c.line1 = line1;
      c.line2 = line2;
      c.line3 = line3;

      return c;
    },
    getX(o) {
      return (
        this.lastzoomPoint.x +
        (o.pointer.x - this.zoomPoint.x - this.relativeMouseX) /
          this.canvas.getZoom()
      );
    },
    getY(o) {
      return (
        this.lastzoomPoint.y +
        (o.pointer.y - this.zoomPoint.y - this.relativeMouseY) /
          this.canvas.getZoom()
      );
    },
    // 缩放后重置原点
    resetOriginAfterZoom() {
      this.lastzoomPoint.x =
        this.lastzoomPoint.x +
        (this.zoomPoint.x - this.lastmousePoint.x - this.relativeMouseX) /
          this.lastzoom;
      this.lastzoomPoint.y =
        this.lastzoomPoint.y +
        (this.zoomPoint.y - this.lastmousePoint.y - this.relativeMouseY) /
          this.lastzoom;

      this.lastmousePoint.x = this.zoomPoint.x;
      this.lastmousePoint.y = this.zoomPoint.y;
      this.lastzoom = this.zoom;

      this.tempmouseX = this.relativeMouseX;
      this.tempmouseY = this.relativeMouseY;
      this.relativeMouseX = 0;
      this.relativeMouseY = 0;
    },
  },
};
</script>
 
<style lang="scss" scoped>
@import "../css/Home.scss";
canvas {
  border: 2px dashed yellow;
}
</style>
